<template><div><p>本文档最新版为 <a href="https://learnku.com/docs/laravel/10.x" target="_blank" rel="noopener noreferrer">10.x</a>，旧版本可能放弃维护，推荐阅读最新版！</p>
<h2 id="数据库-快速入门" tabindex="-1"><a class="header-anchor" href="#数据库-快速入门"><span>数据库：快速入门</span></a></h2>
<ul>
<li><a href="#introduction">简介</a>
<ul>
<li><a href="#configuration">配置</a></li>
<li><a href="#read-and-write-connections">读写分离</a></li>
</ul>
</li>
<li><a href="#running-queries">运行原生 SQL 查询</a>
<ul>
<li><a href="#using-multiple-database-connections">使用多个数据库连接</a></li>
<li><a href="#listening-for-query-events">监听事件查询</a></li>
<li><a href="#monitoring-cumulative-query-time">监控累计查询时间</a></li>
</ul>
</li>
<li><a href="#database-transactions">数据库事务</a></li>
<li><a href="#connecting-to-the-database-cli">链接到数据库 CLI</a></li>
<li><a href="#inspecting-your-databases">检查数据库</a></li>
<li><a href="#monitoring-your-databases">监控数据库</a></li>
</ul>
<h2 id="简介" tabindex="-1"><a class="header-anchor" href="#简介"><span>简介</span></a></h2>
<p>几乎所有的应用程序都需要和数据库进行交互。Laravel 为此提供了一套非常简单易用的数据库交互方式。开发者可以使用原生 SQL，<a href="https://learnku.com/docs/laravel/11.x/queriesmd" target="_blank" rel="noopener noreferrer">查询构造器</a>，以及<a href="https://learnku.com/docs/laravel/11.x/eloquentmd" target="_blank" rel="noopener noreferrer">Eloquent ORM</a>，等方式与数据库交互。目前，Laravel 为以下五种数据库提供了官方支持：</p>
<ul>
<li>MariaDB 10.3+ (<a href="https://mariadb.org/about/#maintenance-policy" target="_blank" rel="noopener noreferrer">策略版本</a>)</li>
<li>MySQL 5.7+ ([<a href="https://en.wikipedia.org/wiki/MySQL#Release_history" target="_blank" rel="noopener noreferrer">策略版本</a>)</li>
<li>PostgreSQL 10.0+ ([<a href="https://www.postgresql.org/support/versioning/" target="_blank" rel="noopener noreferrer">策略版本</a>)</li>
<li>SQLite 3.35.0+</li>
<li>SQL Server 2017+ ([<a href="https://docs.microsoft.com/en-us/lifecycle/products/?products=sql-server" target="_blank" rel="noopener noreferrer">策略版本</a>)</li>
</ul>
<h3 id="配置" tabindex="-1"><a class="header-anchor" href="#配置"><span>配置</span></a></h3>
<p>Laravel 数据库服务的配置位于应用程序的 <code v-pre>config/database.php</code> 配置文件中。在此文件中，您可以定义所有数据库连接，并指定默认情况下应使用的连接。此文件中的大多数配置选项由应用程序环境变量的值驱动。本文件提供了 Laravel 支持的大多数数据库系统的示例。</p>
<p>在默认情况下，Laravel 的示例 <a href="https://learnku.com/docs/laravel/11.x/configurationmd#environment-configuration" target="_blank" rel="noopener noreferrer">环境配置</a> 使用了 <a href="https://learnku.com/docs/laravel/11.x/sailmd" target="_blank" rel="noopener noreferrer">Laravel Sail</a>，Laravel Sail 是一种用于在本地开发 Laravel 应用的 Docker 配置。但你依然可以根据本地数据库的需要修改数据库配置。</p>
<h4 id="sqlite-配置" tabindex="-1"><a class="header-anchor" href="#sqlite-配置"><span>SQLite 配置</span></a></h4>
<p>SQLite数据库包含在文件系统的单个文件中。你可以在终端上使用 <code v-pre>touch</code> 命令创建一个新的SQLite数据库：<code v-pre>touch database/database.sqlite</code>。创建数据库之后，你可以通过在环境变量 <code v-pre>DB_DATABASE</code> 中设置数据库的绝对路径，轻松地配置环境变量来指向这个数据库：</p>
<div class="language-ini line-numbers-mode" data-highlighter="prismjs" data-ext="ini" data-title="ini"><pre v-pre class="language-ini"><code><span class="line"><span class="token key attr-name">DB_CONNECTION</span><span class="token punctuation">=</span><span class="token value attr-value">sqlite</span></span>
<span class="line"><span class="token key attr-name">DB_DATABASE</span><span class="token punctuation">=</span><span class="token value attr-value">/absolute/path/to/database.sqlite</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div></div></div><p>默认情况下，对SQLite连接启用外键约束。如果你想禁用它们，你应该将 <code v-pre>DB_FOREIGN_KEYS</code> 环境变量设置为 <code v-pre>false</code>：</p>
<div class="language-ini line-numbers-mode" data-highlighter="prismjs" data-ext="ini" data-title="ini"><pre v-pre class="language-ini"><code><span class="line"><span class="token key attr-name">DB_FOREIGN_KEYS</span><span class="token punctuation">=</span><span class="token value attr-value">false</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p>[!注意]<br>
如果你使用<a href="https://learnku.com/docs/laravel/11.x/installationmd#creating-a-laravel-project" target="_blank" rel="noopener noreferrer">Laravel安装程序</a>来创建你的Laravel应用程序，并选择SQLite作为你的数据库，Laravel将自动创建一个 <code v-pre>database/database.sqlite</code> 文件运行默认的<a href="https://learnku.com/docs/laravel/11.x/migrationsmd" target="_blank" rel="noopener noreferrer">数据库迁移</a>。</p>
</blockquote>
<h4 id="microsoft-sql-server-配置" tabindex="-1"><a class="header-anchor" href="#microsoft-sql-server-配置"><span>Microsoft SQL Server 配置</span></a></h4>
<p>要使用Microsoft SQL Server数据库，您应该确保安装了 <code v-pre>sqlsrv</code> and <code v-pre>pdo_sqlsrv</code> PHP扩展以及它们可能需要的任何依赖项，例如Microsoft SQL ODBC驱动程序。</p>
<h4 id="使用url配置" tabindex="-1"><a class="header-anchor" href="#使用url配置"><span>使用URL配置</span></a></h4>
<p>通常，数据库连接使用多个配置值进行配置，例如 <code v-pre>host</code>, <code v-pre>database</code>, <code v-pre>username</code>, <code v-pre>password</code> 等。这些配置值中的每一个都有自己相应的环境变量。这意味着在生产服务器上配置数据库连接信息时，需要管理几个环境变量。</p>
<p>部分数据库托管平台（如 AWS 和 Heroku）会提供了包含所有连接信息的数据库「URL」。它们通常看起来像这样：</p>
<div class="language-html line-numbers-mode" data-highlighter="prismjs" data-ext="html" data-title="html"><pre v-pre class="language-html"><code><span class="line">mysql://root:password@127.0.0.1/forge?charset=UTF-8</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>这些 URL 通常遵循标准模式约定：</p>
<div class="language-html line-numbers-mode" data-highlighter="prismjs" data-ext="html" data-title="html"><pre v-pre class="language-html"><code><span class="line">driver://username:password@host:port/database?options</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>为了方便起见，Laravel 支持使用这些 URL 替代传统的配置项来配置你的数据库。如果配置项 <code v-pre>url</code> （或其对应的环境变量 <code v-pre>DATABASE_URL</code> ）存在，那么 Laravel 将会尝试从 URL 中提取数据库连接以及凭证信息。</p>
<h3 id="读写分离" tabindex="-1"><a class="header-anchor" href="#读写分离"><span>读写分离</span></a></h3>
<p>有时候你可能会希望使用一个数据库连接来执行 <code v-pre>SELECT</code> 语句，而 <code v-pre>INSERT</code>、<code v-pre>UPDATE</code> 和 <code v-pre>DELETE</code> 语句则由另一个数据库连接来执行。在 Laravel 中，无论你是使用原生 SQL 查询、查询构造器 或是 <code v-pre>Eloquent ORM</code>，都能轻松实现读写分离。</p>
<p>为了弄明白如何配置读写分离，我们先来看个例子：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token string single-quoted-string">'mysql'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">    <span class="token string single-quoted-string">'read'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'host'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'192.168.1.1'</span><span class="token punctuation">,</span></span>
<span class="line">            <span class="token string single-quoted-string">'196.168.1.2'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'write'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">        <span class="token string single-quoted-string">'host'</span> <span class="token operator">=></span> <span class="token punctuation">[</span></span>
<span class="line">            <span class="token string single-quoted-string">'196.168.1.3'</span><span class="token punctuation">,</span></span>
<span class="line">        <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'sticky'</span> <span class="token operator">=></span> <span class="token constant boolean">true</span><span class="token punctuation">,</span></span>
<span class="line"></span>
<span class="line">    <span class="token string single-quoted-string">'database'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'DB_DATABASE'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'laravel'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'username'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'DB_USERNAME'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'root'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'password'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'DB_PASSWORD'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">''</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'unix_socket'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'DB_SOCKET'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">''</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'charset'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'DB_CHARSET'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'utf8mb4'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'collation'</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'DB_COLLATION'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'utf8mb4_0900_ai_ci'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'prefix'</span> <span class="token operator">=></span> <span class="token string single-quoted-string">''</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'prefix_indexes'</span> <span class="token operator">=></span> <span class="token constant boolean">true</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'strict'</span> <span class="token operator">=></span> <span class="token constant boolean">true</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'engine'</span> <span class="token operator">=></span> <span class="token constant">null</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token string single-quoted-string">'options'</span> <span class="token operator">=></span> <span class="token function">extension_loaded</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'pdo_mysql'</span><span class="token punctuation">)</span> <span class="token operator">?</span> <span class="token function">array_filter</span><span class="token punctuation">(</span><span class="token punctuation">[</span></span>
<span class="line">        <span class="token class-name static-context">PDO</span><span class="token operator">::</span><span class="token constant">MYSQL_ATTR_SSL_CA</span> <span class="token operator">=></span> <span class="token function">env</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'MYSQL_ATTR_SSL_CA'</span><span class="token punctuation">)</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">]</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"><span class="token punctuation">]</span><span class="token punctuation">,</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>请注意，我们在数据库配置中加入了三个键，分别是： <code v-pre>read</code>, <code v-pre>write</code> 以及 <code v-pre>sticky</code> 。<code v-pre>read</code> 和 <code v-pre>write</code> 的值是一个只包含 <code v-pre>host</code> 键的数组。这代表其他的数据库选项将会从主 <code v-pre>mysql</code> 配置中获取。</p>
<p>如果你想要覆写主 <code v-pre>mysql</code> 配置，只需要将需要覆写的值放到 <code v-pre>read</code> 和 <code v-pre>write</code>数组里即可。所以，在这个例子中，<code v-pre>192.168.1.1</code> 将会被用作「读」连接主机，而 <code v-pre>192.168.1.3</code> 将作为「写」连接主机。这两个连接将共享 <code v-pre>mysql</code> 数组中的各项配置，如数据库凭证（用户名、密码）、前缀、字符编码等。如果 <code v-pre>host</code> 数组中存在多个值，<code v-pre>Laravel</code> 将会为每个连接随机选取所使用的数据库主机。</p>
<h4 id="sticky-选项" tabindex="-1"><a class="header-anchor" href="#sticky-选项"><span><code v-pre>sticky</code> 选项</span></a></h4>
<p><code v-pre>sticky</code> 是一个 可选 值，它用于允许 <code v-pre>Laravel</code> 立即读取在当前请求周期内写入到数据库的记录。若 <code v-pre>sticky</code> 选项被启用，且在当前请求周期中执行过「写」操作，那么在这之后的所有「读」操作都将使用「写」连接。这样可以确保同一个请求周期中写入的数据库可以被立即读取到，从而避免主从同步延迟导致的数据不一致。不过是否启用它取决于项目的实际需求。</p>
<h2 id="执行原生-sql-查询" tabindex="-1"><a class="header-anchor" href="#执行原生-sql-查询"><span>执行原生 SQL 查询</span></a></h2>
<p>一旦配置好数据库连接，你就可以使用 <code v-pre>DB</code> Facade 来执行查询。<code v-pre>DB</code> Facade 为每种类型的查询都提供了相应的方法：<code v-pre>select</code>、<code v-pre>update</code>、<code v-pre>insert</code>、<code v-pre>delete</code> 以及 <code v-pre>statement</code>。</p>
<h4 id="执行-select-查询" tabindex="-1"><a class="header-anchor" href="#执行-select-查询"><span>执行 SELECT 查询</span></a></h4>
<p>你可以使用 <code v-pre>DB</code> Facade 的 <code v-pre>select</code> 方法来执行一个基础的 SELECT 查询：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Http<span class="token punctuation">\</span>Controllers<span class="token punctuation">\</span>Controller</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>View<span class="token punctuation">\</span>View</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">UserController</span> <span class="token keyword">extends</span> <span class="token class-name">Controller</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 显示所有应用程序用户的列表。</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">index</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token class-name return-type">View</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token variable">$users</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'select * from users where active = ?'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">        <span class="token keyword">return</span> <span class="token function">view</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'user.index'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'users'</span> <span class="token operator">=></span> <span class="token variable">$users</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>传递给 <code v-pre>select</code> 方法的第一个参数是一个原生 SQL 查询语句，而第二个参数则是需要绑定到查询中的参数值。通常，这些值用于约束 <code v-pre>where</code> 语句。使用参数绑定可以有效防止 SQL 注入。</p>
<p><code v-pre>select</code> 方法将始终返回一个包含查询结果的数组。数组中的每个结果都对应一个数据库记录的 <code v-pre>stdClass</code> 对象：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'select * from users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token variable">$users</span> <span class="token keyword">as</span> <span class="token variable">$user</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token keyword">echo</span> <span class="token variable">$user</span><span class="token operator">-></span><span class="token property">name</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="选择标量值" tabindex="-1"><a class="header-anchor" href="#选择标量值"><span>选择标量值</span></a></h4>
<p>有时你的数据库查询可能得到一个单一的标量值。而不是需要从记录对象中检索查询的标量结果，Laravel 允许你直接使用 <code v-pre>scalar</code> 方法检索此值:</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$burgers</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">scalar</span><span class="token punctuation">(</span></span>
<span class="line">    <span class="token string double-quoted-string">"select count(case when food = 'burger' then 1 end) as burgers from menu"</span></span>
<span class="line"><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="选择多个结果集" tabindex="-1"><a class="header-anchor" href="#选择多个结果集"><span>选择多个结果集</span></a></h4>
<p>如果你的应用程序调用返回多个结果集的存储过程，可以使用 <code v-pre>selectResultSets</code> 方法来检索存储过程返回的所有结果集：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token punctuation">[</span><span class="token variable">$options</span><span class="token punctuation">,</span> <span class="token variable">$notifications</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">selectResultSets</span><span class="token punctuation">(</span></span>
<span class="line">    <span class="token string double-quoted-string">"CALL get_user_options_and_notifications(?)"</span><span class="token punctuation">,</span> <span class="token variable">$request</span><span class="token operator">-></span><span class="token function">user</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token property">id</span></span>
<span class="line"><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="使用命名绑定" tabindex="-1"><a class="header-anchor" href="#使用命名绑定"><span>使用命名绑定</span></a></h4>
<p>除了使用 <code v-pre>?</code> 表示参数绑定外，你还可以使用命名绑定的形式来执行一个查询：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$results</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">select</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'select * from users where id = :id'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token string single-quoted-string">'id'</span> <span class="token operator">=></span> <span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="执行-insert-语句" tabindex="-1"><a class="header-anchor" href="#执行-insert-语句"><span>执行 Insert 语句</span></a></h4>
<p>你可以使用 <code v-pre>DB</code> Facade 的 <code v-pre>insert</code> 方法来执行语句。跟 <code v-pre>select</code> 方法一样，该方法的第一个和第二个参数分别是原生 SQL 语句和绑定的数据：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">insert</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'insert into users (id, name) values (?, ?)'</span><span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'Marc'</span><span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="执行-update-语句" tabindex="-1"><a class="header-anchor" href="#执行-update-语句"><span>执行 Update 语句</span></a></h4>
<p><code v-pre>update</code> 方法用于更新数据库中现有的记录。该方法将会返回受到本次操作影响的记录行数：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$affected</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">update</span><span class="token punctuation">(</span></span>
<span class="line">    <span class="token string single-quoted-string">'update users set votes = 100 where name = ?'</span><span class="token punctuation">,</span></span>
<span class="line">    <span class="token punctuation">[</span><span class="token string single-quoted-string">'Anita'</span><span class="token punctuation">]</span></span>
<span class="line"><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="执行-delete-语句" tabindex="-1"><a class="header-anchor" href="#执行-delete-语句"><span>执行 Delete 语句</span></a></h4>
<p><code v-pre>delete</code> 函数被用于删除数据库中的记录。它的返回值与 <code v-pre>update</code> 函数相同，返回本次操作受影响的总行数。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$deleted</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'delete from users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="执行指定的-sql" tabindex="-1"><a class="header-anchor" href="#执行指定的-sql"><span>执行指定的 SQL</span></a></h4>
<p>部分 SQL 语句不返回任何值。在这种情况下，你可能需要使用 <code v-pre>DB::statement($sql)</code> 来执行你的 SQL 语句。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">statement</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'drop table users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="直接执行-sql" tabindex="-1"><a class="header-anchor" href="#直接执行-sql"><span>直接执行 SQL</span></a></h4>
<p>有时候你可能想执行一段 SQL 语句，但不需要进行 SQL 预处理绑定。这种情况下你可以使用 <code v-pre>DB::unprepared($sql)</code> 来执行你的 SQL 语句。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">unprepared</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update users set votes = 100 where name = "Dries"'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p><strong>注意</strong><br>
未经过预处理 SQL 的语句不绑定参数，它们可能容易受到 SQL 注入的攻击。在没有必要的理由的情况下，你不应直接在 SQL 中使用用户传入的数据。</p>
</blockquote>
<h4 id="在事务中的隐式提交" tabindex="-1"><a class="header-anchor" href="#在事务中的隐式提交"><span>在事务中的隐式提交</span></a></h4>
<p>在事务中使用 <code v-pre>DB::statement($sql)</code> 与 <code v-pre>DB::unprepared($sql)</code> 时，你必须要谨慎处理，避免 SQL 语句产生<a href="https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html" target="_blank" rel="noopener noreferrer">隐式提交</a>。这些语句会导致数据库引擎间接地提交整个事务，让 Laravel 丢失数据库当前的事务级别。创建数据库表就是一个这样的语句的例子：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">unprepared</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'create table a (col varchar(1) null)'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>请参考 <a href="https://dev.mysql.com/doc/refman/8.0/en/implicit-commit.html" target="_blank" rel="noopener noreferrer">MySQL 官方手册</a>以了解更多隐式提交的信息。</p>
<h3 id="使用多数据库连接" tabindex="-1"><a class="header-anchor" href="#使用多数据库连接"><span>使用多数据库连接</span></a></h3>
<p>如果你在配置文件 <code v-pre>config/database.php</code> 中定义了多个数据库连接的话，你可以通过 <code v-pre>DB</code> Facade 的 <code v-pre>connection</code> 方法来使用它们。传递给 <code v-pre>connection</code> 方法的连接名称应该是你在 <code v-pre>config/database.php</code> 里或者通过 <code v-pre>config</code> 助手函数在运行时配置的连接之一：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$users</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">connection</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'sqlite'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">select</span><span class="token punctuation">(</span><span class="token comment">/* ... */</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你也可以使用一个连接实例上的 <code v-pre>getPdo</code> 方法来获取底层的 PDO 实例：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$pdo</span> <span class="token operator">=</span> <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">connection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">getPdo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h3 id="监听查询事件" tabindex="-1"><a class="header-anchor" href="#监听查询事件"><span>监听查询事件</span></a></h3>
<p>如果你想要获取程序执行的每一条 SQL 语句，可以使用 Db facade 的 listen 方法。该方法对查询日志和调试非常有用，你可以在<a href="https://learnku.com/docs/laravel/11.x/providersmd" target="_blank" rel="noopener noreferrer">服务提供者</a>中使用 boot 方法注册查询监听器。</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Events<span class="token punctuation">\</span>QueryExecuted</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>ServiceProvider</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">AppServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 注册任意应用服务</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">register</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 引导任意应用服务</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">QueryExecuted</span> <span class="token variable">$query</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token comment">// $query->sql;</span></span>
<span class="line">            <span class="token comment">// $query->bindings;</span></span>
<span class="line">            <span class="token comment">// $query->time;</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="监控累积查询时间" tabindex="-1"><a class="header-anchor" href="#监控累积查询时间"><span>监控累积查询时间</span></a></h3>
<p>现代Web应用程序的常见性能瓶颈之一是查询数据库所花费的时间。幸运的是，当Laravel在单个请求中花费过多时间查询数据库时，它可以调用您选择的闭包或回调。要开始使用它，请提供查询时间阈值（以毫秒为单位）和闭包给 <code v-pre>whenQueryingForLongerThan</code> 方法。您可以在<a href="https://learnku.com/docs/laravel/11.x/providersmd" target="_blank" rel="noopener noreferrer">服务提供者</a>的 <code v-pre>boot</code> 方法中调用此方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token php language-php"><span class="token delimiter important">&lt;?php</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">namespace</span> <span class="token package">App<span class="token punctuation">\</span>Providers</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Connection</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>ServiceProvider</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Events<span class="token punctuation">\</span>QueryExecuted</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token keyword">class</span> <span class="token class-name-definition class-name">AppServiceProvider</span> <span class="token keyword">extends</span> <span class="token class-name">ServiceProvider</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 注册任意应用服务</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">register</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token comment">// ...</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"></span>
<span class="line">    <span class="token doc-comment comment">/**</span>
<span class="line">     * 引导任意应用服务</span>
<span class="line">     */</span></span>
<span class="line">    <span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line">    <span class="token punctuation">{</span></span>
<span class="line">        <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">whenQueryingForLongerThan</span><span class="token punctuation">(</span><span class="token number">500</span><span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">Connection</span> <span class="token variable">$connection</span><span class="token punctuation">,</span> <span class="token class-name type-declaration">QueryExecuted</span> <span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">            <span class="token comment">// 通知开发团队...</span></span>
<span class="line">        <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h2 id="数据库事务" tabindex="-1"><a class="header-anchor" href="#数据库事务"><span>数据库事务</span></a></h2>
<p>你可以使用 <code v-pre>DB</code> 门面提供的 <code v-pre>transaction</code> 方法在数据库事务中运行一系列操作。如果在事务闭包内抛出异常，事务将自动回滚并重新抛出异常。如果闭包执行成功，事务将自动提交。在使用 <code v-pre>transaction</code> 方法时，您不需要担心手动回滚或提交：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">transaction</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update users set votes = 1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'delete from posts'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="处理死锁" tabindex="-1"><a class="header-anchor" href="#处理死锁"><span>处理死锁</span></a></h4>
<p><code v-pre>transaction</code> 方法接受一个可选的第二个参数，该参数定义发生死锁时事务应重试的次数。一旦这些尝试用尽，就会抛出一个异常：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">transaction</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">update</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'update users set votes = 1'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line">    <span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">delete</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'delete from posts'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h4 id="手动执行事务" tabindex="-1"><a class="header-anchor" href="#手动执行事务"><span>手动执行事务</span></a></h4>
<p>如果你想要手动处理事务并完全控制回滚和提交，可以使用 <code v-pre>DB</code> facade 提供的 <code v-pre>beginTransaction</code> 方法：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>DB</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">beginTransaction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你可以通过 <code v-pre>rollBack</code> 方法回滚事务：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">rollBack</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>最后，你可以通过 <code v-pre>commit</code> 方法提交事务：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token class-name static-context">DB</span><span class="token operator">::</span><span class="token function">commit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><blockquote>
<p><strong>技巧</strong><br>
DB 门面的事务方法还可以用于控制<a href="https://learnku.com/docs/laravel/11.x/queriesmd" target="_blank" rel="noopener noreferrer">查询构造器</a> 和 <a href="https://learnku.com/docs/laravel/11.x/eloquentmd" target="_blank" rel="noopener noreferrer">Eloquent ORM</a>。</p>
</blockquote>
<h2 id="连接到数据库-cl" tabindex="-1"><a class="header-anchor" href="#连接到数据库-cl"><span>连接到数据库 CL</span></a></h2>
<p>如果你想连接到数据库的 CLI，则可以使用 <code v-pre>db</code> Artisan 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan db</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果需要，你可以指定数据库连接名称以连接到不是默认连接的数据库连接：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan db mysql</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="检查你的数据库" tabindex="-1"><a class="header-anchor" href="#检查你的数据库"><span>检查你的数据库</span></a></h2>
<p>使用 <code v-pre>db:show</code> 和 <code v-pre>db:table</code> Artisan 命令，你可以深入了解数据库及其相关表。要查看数据库的概述，包括它的大小、类型、打开的连接数及其表的摘要，你可以使用 <code v-pre>db:show</code> 命令：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan db:show</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>你可以通过 <code v-pre>--database</code> 选项向命令提供数据库连接名称来指定应该检查哪个数据库连接:</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan db:show <span class="token parameter variable">--database</span><span class="token operator">=</span>pgsql</span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>如果希望在命令的输出中包含表行计数和数据库视图详细信息，你可以分别提供 <code v-pre>--counts</code> 和 <code v-pre>--views</code> 选项。在大型数据库上，检索行数和视图详细信息可能很慢:</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan db:show <span class="token parameter variable">--counts</span> <span class="token parameter variable">--views</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>此外，你可以使用以下 <code v-pre>Schema</code> 方法来检查您的数据库：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Schema</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token variable">$tables</span> <span class="token operator">=</span> <span class="token class-name static-context">Schema</span><span class="token operator">::</span><span class="token function">getTables</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$views</span> <span class="token operator">=</span> <span class="token class-name static-context">Schema</span><span class="token operator">::</span><span class="token function">getViews</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$columns</span> <span class="token operator">=</span> <span class="token class-name static-context">Schema</span><span class="token operator">::</span><span class="token function">getColumns</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$indexes</span> <span class="token operator">=</span> <span class="token class-name static-context">Schema</span><span class="token operator">::</span><span class="token function">getIndexes</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token variable">$foreignKeys</span> <span class="token operator">=</span> <span class="token class-name static-context">Schema</span><span class="token operator">::</span><span class="token function">getForeignKeys</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>你可以使用 <code v-pre>connection</code> 方法指定数据库连接：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token variable">$columns</span> <span class="token operator">=</span> <span class="token class-name static-context">Schema</span><span class="token operator">::</span><span class="token function">connection</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'sqlite'</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token function">getColumns</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'users'</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h4 id="表的摘要信息" tabindex="-1"><a class="header-anchor" href="#表的摘要信息"><span>表的摘要信息</span></a></h4>
<p>如果你想获得数据库中单张表的概览，你可以执行 <code v-pre>db:table</code> Artisan 命令。这个命令提供了一个数据库表的概览，包括它的列、类型、属性、键和索引:</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan db:table <span class="token function">users</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><h2 id="监视数据库" tabindex="-1"><a class="header-anchor" href="#监视数据库"><span>监视数据库</span></a></h2>
<p>使用 <code v-pre>db:monitor</code> Artisan 命令，如果你的数据库正在管理超过指定数量的打开连接，可以通过 Laravel 调度触发 <code v-pre>Illuminate\Database\Events\DatabaseBusy</code> 事件。</p>
<p>开始，你应该将 <code v-pre>db:monitor</code> 命令安排为<a href="https://learnku.com/docs/laravel/11.x/schedulingmd" target="_blank" rel="noopener noreferrer">每分钟运行一次</a>。 该命令接受要监视的数据库连接配置的名称，以及在分派事件之前应允许的最大打开连接数：</p>
<div class="language-bash line-numbers-mode" data-highlighter="prismjs" data-ext="sh" data-title="sh"><pre v-pre class="language-bash"><code><span class="line">php artisan db:monitor <span class="token parameter variable">--databases</span><span class="token operator">=</span>mysql,pgsql <span class="token parameter variable">--max</span><span class="token operator">=</span><span class="token number">100</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div></div></div><p>仅调度此命令不足以触发通知提醒你打开连接的数量。当命令遇到一个超过阈值的打开连接数的数据库时，会调度一个 <code v-pre>DatabaseBusy</code> 事件。你应该在应用程序的 <code v-pre>AppServiceProvider</code> 中监听此事件，以便向你或你的开发团队发送通知：</p>
<div class="language-php line-numbers-mode" data-highlighter="prismjs" data-ext="php" data-title="php"><pre v-pre class="language-php"><code><span class="line"><span class="token keyword">use</span> <span class="token package">App<span class="token punctuation">\</span>Notifications<span class="token punctuation">\</span>DatabaseApproachingMaxConnections</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Database<span class="token punctuation">\</span>Events<span class="token punctuation">\</span>DatabaseBusy</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Event</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token keyword">use</span> <span class="token package">Illuminate<span class="token punctuation">\</span>Support<span class="token punctuation">\</span>Facades<span class="token punctuation">\</span>Notification</span><span class="token punctuation">;</span></span>
<span class="line"></span>
<span class="line"><span class="token doc-comment comment">/**</span>
<span class="line"> * 为应用程序注册任何其他事件。</span>
<span class="line"> */</span></span>
<span class="line"><span class="token keyword">public</span> <span class="token keyword">function</span> <span class="token function-definition function">boot</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">:</span> <span class="token keyword return-type">void</span></span>
<span class="line"><span class="token punctuation">{</span></span>
<span class="line">    <span class="token class-name static-context">Event</span><span class="token operator">::</span><span class="token function">listen</span><span class="token punctuation">(</span><span class="token keyword">function</span> <span class="token punctuation">(</span><span class="token class-name type-declaration">DatabaseBusy</span> <span class="token variable">$event</span><span class="token punctuation">)</span> <span class="token punctuation">{</span></span>
<span class="line">        <span class="token class-name static-context">Notification</span><span class="token operator">::</span><span class="token function">route</span><span class="token punctuation">(</span><span class="token string single-quoted-string">'mail'</span><span class="token punctuation">,</span> <span class="token string single-quoted-string">'dev@example.com'</span><span class="token punctuation">)</span></span>
<span class="line">                <span class="token operator">-></span><span class="token function">notify</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">DatabaseApproachingMaxConnections</span><span class="token punctuation">(</span></span>
<span class="line">                    <span class="token variable">$event</span><span class="token operator">-></span><span class="token property">connectionName</span><span class="token punctuation">,</span></span>
<span class="line">                    <span class="token variable">$event</span><span class="token operator">-></span><span class="token property">connections</span></span>
<span class="line">                <span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line">    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></span>
<span class="line"><span class="token punctuation">}</span></span>
<span class="line"></span></code></pre>
<div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote>
<p>本译文仅用于学习和交流目的，转载请务必注明文章译者、出处、和本文链接<br>
我们的翻译工作遵照 <a href="https://learnku.com/docs/guide/cc4.0/6589" target="_blank" rel="noopener noreferrer">CC 协议</a>，如果我们的工作有侵犯到您的权益，请及时联系我们。</p>
</blockquote>
<hr>
<blockquote>
<p>原文地址：<a href="https://learnku.com/docs/laravel/11.x/databasemd/16696" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/da...</a></p>
<p>译文地址：<a href="https://learnku.com/docs/laravel/11.x/databasemd/16696" target="_blank" rel="noopener noreferrer">https://learnku.com/docs/laravel/11.x/da...</a></p>
</blockquote>
</div></template>


